package chances.wechat.service;

import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import chances.epg.commons.utils.PathUtils;
import chances.wechat.config.WeChatMvcConfig;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

@Component
public class ProxyService {
    
    @Autowired
    WeChatMvcConfig weChatMvcConfig;

    @Value("${tvportal.proxy.url:http://localhost:8082}")
    private String proxyUrl;

    @Value("${tvportal.proxy.connectTimeout:2}")
    private int connectTimeout;

    @Value("${tvportal.proxy.readTimeout:20}")
    private int readTimeout;

    Logger logger = LoggerFactory.getLogger(this.getClass());

    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    public void proxy(HttpServletRequest request, HttpServletResponse httpResponse,String path) throws IOException {
        try {
            String url = PathUtils.join(weChatMvcConfig.getWgHost(),path);
            OkHttpClient okHttpClient = new OkHttpClient()
                    .newBuilder().connectTimeout(weChatMvcConfig.getConnectTimeOut(), TimeUnit.SECONDS)
                    .readTimeout(weChatMvcConfig.getReadTimeOut(), TimeUnit.SECONDS)
                    .build();
            
            
            if (StringUtils.isNotBlank(request.getQueryString())) {
                url = url + "?" + request.getQueryString();
            }
            
            FormBody.Builder builder = new FormBody.Builder();

            Map<String, String[]> map = request.getParameterMap();

            if (map != null) {
                for (Entry<String, String[]> entry : map.entrySet()) {
                    builder.add(entry.getKey(), entry.getValue()[0]);
                }
            }
            RequestBody requestBody = builder.build();

            Request clientRequest = null;
            if ("POST".equals(request.getMethod())) {
                RequestBody body = RequestBody.create(JSON, binaryReader(request));
                clientRequest = new Request.Builder().url(url).post(body).build();
            	
//            	clientRequest = new Request.Builder().url(url).post(requestBody).build();
            } else {
                clientRequest = new Request.Builder().url(url).get().build();
            }
            Call call = okHttpClient.newCall(clientRequest);

            Response resp = call.execute();

            String content = resp.body().string();

            httpResponse.setStatus(resp.code());
            httpResponse.setCharacterEncoding("UTF-8");
            httpResponse.setContentType(resp.header("Content-Type"));
            httpResponse.getWriter().append(content);
        } catch (Exception e) {
            e.printStackTrace();
            httpResponse.setStatus(500);
            httpResponse.getWriter().append(e.getMessage());
        }

    }

    public String getPath(HttpServletRequest request) {
        String path = request.getRequestURI();
        String servletPath = request.getServletPath();

        //String result = StringUtils.substring(path, path.indexOf(servletPath));
        String result = StringUtils.replace(path, "/proxy", "");
        return result;
    }

    public byte[] binaryReader(HttpServletRequest request) throws IOException {

        int len = request.getContentLength();
        if (len == 0) {
            return "{}".getBytes("utf-8");
        }

        ServletInputStream iii = request.getInputStream();
        byte[] buffer = new byte[len];
        iii.read(buffer, 0, len);

        return buffer;
    }
}
